package com.learn.mybtsp.config;


import com.learn.mybtsp.service.SecurityUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //注解，开启授权
public class SecurityConfig {
    //开启密码加密
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    // 生成密码加密
    public static void main(String[] args) {
        System.out.println(new BCryptPasswordEncoder().encode("1234"));
    }
    @Autowired
    private SecurityUserService securityUserService;

    //配置过滤器
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.userDetailsService(securityUserService);
        //开启HttpSecurity的配置
        http.authorizeRequests()
                //访问/admin/**模式的url必须具备admin的角色，没有权限时会返回403
                .antMatchers("/user/admin/**").hasRole("ADMIN")
                // /user/**模式的url，具有ADMIN USER都可以访问
//                .antMatchers("/user/**").access("hasAnyRole('ADMIN','USER')")
                // .anyRequest().authenticated() //剩下的接口,登录就可以访问
                // 使用访问控制 自己实现service处理，会接收两个参数
                .anyRequest().access("@authService.auth(request,authentication)")
                .and()
                //开启表单验证
                .formLogin()
                .loginPage("/index.html") //自定义的登录页面
                .loginProcessingUrl("/login") //登录处理接口
                .usernameParameter("username") //登录接口用户名的key，默认为username
                .passwordParameter("password") //登录时的密码key，默认为password
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");
                        PrintWriter out = response.getWriter();
                        out.write("success");
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");
                        PrintWriter out = response.getWriter();
                        out.write("fail");
                    }
                })
                .permitAll()  //表单登录相关的接口 都放行
                .and().logout().logoutUrl("/logout")
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.setContentType("application/json;charset=utf-8");
                        PrintWriter out = response.getWriter();
                        out.write("logout success");
                        out.flush();
                    }
                })
                .permitAll() //表单登出的接口放行
                .and().httpBasic()
                .and().cors()
                .and().csrf().disable(); //如果是自定义登录，则需要关闭 csrf

        return http.build();
    }

    //用户认证,创建2个user，并设置角色role，将数据创建在内存中的
//    @Bean
//    public UserDetailsService userDetailsService(){
//
//        //创建两个用户
//        UserDetails user =
//                User.withUsername("admin")
//                        //密码1234
//                        .password("$2a$10$zcisk1XYqooA9CGAIfGhSOZi0QG/9U8AA9ijeF1dU8dscmsE6Y0NK")
//                        .roles("ADMIN")
//                        .build();
//
//        UserDetails user1 =
//                User.withUsername("user")
//                        //密码1234
//                        .password("$2a$10$hoUNz8qpmLlemaJIAZMfJORFJYlF6g/T5uqoWAH1BkFHhL2BMcEay")
//                        .roles("USER")
//                        .build();
//        //这个方法接收的是UserDetails... users，所以可以传入多个user
//        return new InMemoryUserDetailsManager(user,user1);
//    }

}